#!/bin/sh
#package:odpkg
#desc:Update base system
#type:local
# Este script deberá actualizar los archivos initrd y linux.
# Si se dispone de espacio suficiente, se mantendrá una copia de
# los archivos anteriores con los nombres initrold.gz y linuxold, 
# de modo que sea posible recuperar el sistema base anterior en
# caso de emergencia.

# NOTA: El sistema de arranque estándar funciona sobre vfat, de 
#       modo que es posible que los nombres largos no funcionen
#       correctamente. Deberá tenerse en cuenta esto, así como 
#       las mayúsculas y minúsculas.

# El procedimiento a seguir es el siguiente:
# 1. Verificamos que el sistema base es actualizable (esto es, 
#    que se encuentra en una unidad con acceso de lectura y de
#    escritura). En caso negativo, abortamos.
# 2. Verificamos que hay espacio suficiente en la unidad para
#    los nuevos archivos. Para mayor seguridad, deberán caber
#    hasta 3 pares: el actual, el anterior y el que va a ser
#    instalado. 
# 3. Descargamos los archivos más recientes de la lista de 
#    paquetes instalables. Hay que tener en cuenta que :
#      a. La versión disponible es más reciente que la instalada
#      b. Estos paquetes no serán visibles para el instalador
#         de paquetes normal
#      c. La arquitectura deberá corresponderse EXACTAMENTE con
#         la indicada en /bin/arch
# 4. Al descargar (sin pasos intermedios) guardamos los archivos 
#    como initrd.new y linux.new. Hay que tener en cuenta que
#    probablemente no quepan en el ramdisk.
# 5. Verificamos checksums (cuando la distro lo permita)
# 6. Movemos los archivos del siguiente modo:
#      initrd.gz  => initrold.gz
#      initrd.new => initrd.gz
#      (sync)
#      linux      => linuxold
#      linux.new  => linux   
#      (sync)

BOOTDIR="/mnt/system/"
URLLIST="/tmp/urlavailable.txt"
NEWKERNEL=`grep "/_kernel" $URLLIST | sort | tail -n 1`
NEWINITRD=`grep "/_initrd" $URLLIST | sort | tail -n 1`

# Previo; Garantizamos que existan
touch /var/pkg/installed/_kernel
touch /var/pkg/installed/_initrd
# y actualizamos lista de paquetes, aunque sin salida
/usr/local/opendomo/updatePackageList.sh 2> /dev/null > /dev/null
if touch $BOOTDIR/initrd.ngz && touch $BOOTDIR/linux.new 2>/dev/null
then
	echo "# System directory is available"
else
	echo "#ERR: System directory is read-only"
	exit 7
fi

# Paso 1: Miramos si el sistema es actualizable
if test -w "$BOOTDIR/initrd.gz"; then
	echo "# Initrd found"
else
	echo "#ERR: Missing initrd in $BOOTDIR or write-protected"
	exit 6 
fi 
if test -w "$BOOTDIR/linux"; then
	echo "# Kernel found"
else
	echo "#ERR: Missing kernel file in $BOOTDIR or write-protected"
	exit 5
fi


# Paso 2: miramos si hay versiones disponibles
if test -z "$NEWKERNEL" ; then
	echo "# kernel updates unavailable"
else
	NEWKERNELVERSION=`basename $NEWKERNEL | cut -f 2 -d'-' | cut -f 1 -d'.'`
	NEWINITRDVERSION=`basename $NEWINITRD | cut -f 2 -d'-' | cut -f 1 -d'.'`
fi
if test -z "$NEWINITRD"; then
	echo "# initrd updates unavailable"
else
	OLDKERNELVERSION=`cat /var/pkg/installed/_kernel`
	OLDINITRDVERSION=`cat /var/pkg/installed/_initrd`
fi

# Paso 3: comparamos las versiones con las instaladas y descargamos
if test "$OLDKERNELVERSION" -lt "$NEWKERNELVERSION"; then
	echo "# New kernel version found. Updating ..."
	NEWKERNELURL=`echo $NEWKERNEL | cut -f2 -d';'`
	if wget -q "$NEWKERNELURL" -O /tmp/kernel.gz 2>/dev/null
	then
		if wget -q "$NEWKERNELURL".sha1 -O /tmp/kernel.sha1 2>/dev/null
		then
			SUM=`sha1sum /tmp/kernel.gz | cut -f 1 -d' '`
			if test `cat /tmp/kernel.sha1` != "$SUM"
			then
				echo "#ERR: Hashes not match!"
				exit 2
			fi
		else 
			echo "#ERR: Hash file not found!"
			exit 3
		fi
		# Archivo descargado y verificado
		echo "# Replacing kernel..."
		mv /tmp/kernel.gz $BOOTDIR/linux.new | exit 10
		sync
	else
		echo "#ERR: download failed"
		exit 4
	fi
else
	echo "# Kernel is up to date"
fi

if test "$OLDINITRDVERSION" -lt "$NEWINITRDVERSION"; then
	echo "# New INITRD version found. Updating ..."
	NEWINITRDURL=`echo $NEWINITRD | cut -f2 -d';'`
	if wget -q "$NEWINITRDURL" -O /tmp/initrd.gz 2>/dev/null 
	then
		if wget -q "$NEWINITRDURL".sha1 -O /tmp/initrd.sha1 2>/dev/null
		then
			SUM=`sha1sum /tmp/initrd.gz | cut -f 1 -d' '`
			if test `cat /tmp/initrd.sha1` != "$SUM"
			then
				echo "#ERR: Hashes not match!"
				exit 2
			fi
		else 
			echo "#ERR: Hash file not found!"
			exit 3
		fi
		# Archivo descargado y verificado
		echo "# Replacing initrd..."
		mv /tmp/initrd.gz $BOOTDIR/initrd.ngz | exit 10
		sync
	else
		echo "#ERR: download failed"
		exit 4
	fi
else
	echo "# INITRD is up to date"
fi

# Si ambos archivos han sido descargados y verificados, procedemos al cambio
if test -f $BOOTDIR/initrd.ngz && test -f $BOOTDIR/linux.new; then
	echo "# Replacing boot files"
	mv $BOOTDIR/initrd.gz $BOOTDIR/initrdo.gz | exit 10
	mv $BOOTDIR/initrd.ngz $BOOTDIR/initrd.gz | exit 10 
	mv $BOOTDIR/linux $BOOTDIR/linux.old | exit 10 
	mv $BOOTDIR/linux.new $BOOTDIR/linux | exit 10
	sync
	echo "$NEWINITRDVERSION" > /var/pkg/installed/_initrd
	echo "$NEWKERNELVERSION" > /var/pkg/installed/_kernel
	echo "# System upgraded!"
else
	echo "#ERR Files missing!"
fi
